package com.hospitalsystem.service.impl;

import com.hospitalsystem.dao.DoctorDao;
import com.hospitalsystem.entity.Doctor;
import com.hospitalsystem.entity.Drug;
import com.hospitalsystem.service.DoctorService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Doctor)表服务实现类
 *
 * @author makejava
 * @since 2024-12-28 19:32:24
 */
@Service("doctorService")
public class DoctorServiceImpl implements DoctorService {
    @Resource
    private DoctorDao doctorDao;

    /**
     * 通过ID查询单条数据
     *
     * @param  dId
     * @return 实例对象
     */
    @Override
    public Doctor queryById(String dId) {
        return this.doctorDao.queryById(dId);
    }

    /**
     * 分页查询
     *
     *
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<Doctor> queryByPage(PageRequest pageRequest) {
        int page = (int) pageRequest.getPageNumber(); // 页码，从 1 开始
        int pageSize = pageRequest.getPageSize();

        // 计算 offset，页码从1开始，所以 offset = (page - 1) * pageSize
        int offset = (page - 1) * pageSize;

        long total = this.doctorDao.count();
        List<Doctor> doctors = this.doctorDao.queryAll(offset, pageSize); // 传递其他必要的过滤条件
        return new PageImpl<>(doctors, pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param doctor 实例对象
     * @return 实例对象
     */
    @Override
    public Doctor insert(Doctor doctor) {
        this.doctorDao.insert(doctor);
        return doctor;
    }

    /**
     * 修改数据
     *
     * @param doctor 实例对象
     * @return 实例对象
     */
    @Override
    public Doctor update(Doctor doctor) {
        this.doctorDao.update(doctor);
        return this.queryById(doctor.getDId());
    }

    /**
     * 通过主键删除数据
     *
     * @param  dId
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String dId) {
        return this.doctorDao.deleteById(dId) > 0;
    }

    @Override
    public String login(String dId,String password){
        if(existIdAndPassword(dId,password)){
            return this.doctorDao.login(dId,password);
        }
        else return null;
    }
    @Override
    public boolean existIdAndPassword(String dId,String password){
        return this.doctorDao.existIdAndPassword(dId,password);
    };

    @Override
    public List<Doctor> getAllDoctors() {
        // 查询所有医生信息，不包含剩余名额
        List<Doctor> doctors = doctorDao.findAll();
        return doctors.stream().map(doctor -> new Doctor(doctor.getDId(), doctor.getName(), doctor.getPassword(), doctor.getGender(),
                        doctor.getPhone(), doctor.getType(), doctor.getDepartment()))
                .collect(Collectors.toList());
    }

    @Override
    public List<Doctor> getDoctorsWithAvailableSlots(String arrangeTime) {
        // 处理前端传入的时间，转换为日期时间格式
        Date time = convertToDate(arrangeTime);

        // 计算该时刻所在一小时的开始时间和结束时间
        Date[] timeRange = getTimeRangeForHour(time);
        String startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeRange[0]);
        String endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeRange[1]);

        // 查询所有在该时间段内有剩余名额的医生
        List<Doctor> doctorsWithAvailableSlots = doctorDao.findDoctorsWithAvailableSlots(startTime, endTime);

        // 如果没有符合条件的医生，返回空列表或适当的错误信息
        if (doctorsWithAvailableSlots == null || doctorsWithAvailableSlots.isEmpty()) {
            System.out.println("No doctors found with available slots in the given time range.");
        }


        // 将查询结果转换为 DTO，并返回
        return doctorsWithAvailableSlots.stream().map(doctor -> {
           Integer remainingSlots = doctorDao.findAvailableSlots(doctor.getDId(), startTime, endTime);
            // 检查剩余名额是否为空，如果是空则默认为 0
            if (remainingSlots == null) {
                remainingSlots = 0;
            }
            // 调试代码：打印医生信息及剩余名额
//            System.out.println("调用findAvailableSlots之后");
//            System.out.println("Doctor ID: " + doctor.getDId());
//            System.out.println("Doctor Name: " + doctor.getName());
//            System.out.println("Remaining Slots: " + remainingSlots);

            // 返回 Doctor 对象，包括 remainingSlots 字段
            doctor.setRemainingSlots(remainingSlots);
            return doctor;
        }).collect(Collectors.toList());
    }

    private Date convertToDate(String arrangeTime) {
        try {
            // 根据前端传入的字符串格式解析为 Date
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.parse(arrangeTime);
        } catch (ParseException e) {
            throw new RuntimeException("时间解析失败", e);
        }
    }

    private Date[] getTimeRangeForHour(Date arrangeTime) {
        // 计算该时间所在小时的开始时间和结束时间
        Calendar cal = Calendar.getInstance();
        cal.setTime(arrangeTime);

        // 设置开始时间为当前小时的 00 分 00 秒
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date startTime = cal.getTime();

        // 设置结束时间为当前小时的 59 分 59 秒
        cal.add(Calendar.HOUR, 1);
        cal.add(Calendar.SECOND, -1);
        Date endTime = cal.getTime();

        return new Date[]{startTime, endTime};
    }

    @Override
    public String getNameByDId(String dId){
        return this.doctorDao.getNameByDId(dId);
    }

    @Override
    public List<Doctor> getDoctorsByDepartment(String department){
        return this.doctorDao.getDoctorsByDepartment(department);
    };

    @Override
    public List<Doctor> getDoctorsWithAvailableSlotsByDepartment(String arrangeTime, String department){
        // 处理前端传入的时间，转换为日期时间格式
        Date time = convertToDate(arrangeTime);

        // 计算该时刻所在一小时的开始时间和结束时间
        Date[] timeRange = getTimeRangeForHour(time);
        String startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeRange[0]);
        String endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeRange[1]);

        // 查询所有在该时间段内有剩余名额的医生
        List<Doctor> doctorsWithAvailableSlots = doctorDao.getDoctorsWithAvailableSlotsByDepartment(startTime, endTime,department);

        // 如果没有符合条件的医生，返回空列表或适当的错误信息
        if (doctorsWithAvailableSlots == null || doctorsWithAvailableSlots.isEmpty()) {
            System.out.println("No doctors found with available slots in the given time range.");
        }

        // 将查询结果转换为 DTO，并返回
        return doctorsWithAvailableSlots.stream().map(doctor -> {
            Integer remainingSlots = doctorDao.findAvailableSlots(doctor.getDId(), startTime, endTime);
            // 检查剩余名额是否为空，如果是空则默认为 0
            if (remainingSlots == null) {
                remainingSlots = 0;
            }
            // 调试代码：打印医生信息及剩余名额
//            System.out.println("调用findAvailableSlots之后");
//            System.out.println("Doctor ID: " + doctor.getDId());
//            System.out.println("Doctor Name: " + doctor.getName());
//            System.out.println("Remaining Slots: " + remainingSlots);

            // 返回 Doctor 对象，包括 remainingSlots 字段
            doctor.setRemainingSlots(remainingSlots);
            return doctor;
        }).collect(Collectors.toList());
    }

    @Override
    public Boolean updateIfTake1(String mId){
        updateDrugStockBatch(mId);
        return this.doctorDao.updateIfTake1(mId);
    }

    public void updateDrugStockBatch(String mId) {
        // 获取drug_list字段
        String drugList = doctorDao.getDrugListByMId(mId);

        // 解析药品数据
        List<Drug> drugs= parseDrugList(drugList);
        for (Drug drug : drugs) {
//            System.out.println(drug.getName()+drug.getNumber()); // 自动调用 drug.toString()
            doctorDao.updateDrugStockBatch(drug);
        }
    }

    public List<Drug> parseDrugList(String drugList) {
        List<Drug> drugItems = new ArrayList<>();

        // 按换行符分割药品条目
        String[] drugs = drugList.split("\n");

        for (String drug : drugs) {
            // 按空格分割药品名称和数量
            String[] parts = drug.trim().split(" ");  // 使用trim()去掉首尾空格
            if (parts.length == 2) {
                String name = parts[0].trim();  // 药品名称
                int number = Integer.parseInt(parts[1].trim());  // 药品数量

                Drug d = new Drug();
                d.setName(name);
                d.setNumber(number);

                drugItems.add(d);
            } else {
                // 处理无效的药品条目，如果需要的话
                System.out.println("无效的药品条目：" + drug);
            }
        }

        return drugItems;
    }


    @Override
    public Boolean updateIfTake_1(String mId){
        return this.doctorDao.updateIfTake_1(mId);
    }

    @Override
    public Boolean updateIfPay(String mId){
        return this.doctorDao.updateIfPay(mId);
    }

}
